

use tremor_value::Value;
use tremor_value::StaticNode;
use crate::data_frame::{DataFrame};
use crate::run_plan::{HandResult};
use std::sync::Arc;
use simd_json_derive::Deserialize;
use simd_json::{Writable};
use simd_json::Value as JV;
use crate::data_frame::json::value::*;
use crate::data_frame::value::{ElementValue, RealValue, RealValueType};
use beef::generic::Cow;

pub mod value;

#[derive(Clone)]
pub struct JsonValue{
    json: String,
    value: Value<'static>,
}
impl JsonValue{
    pub fn build_new(mut json: String)->Result<Arc<JsonValue>,()>{
        let tmp_value = match Value::from_str(json.as_mut_str()){
            Ok(t) => {t},
            Err(_e) => {return Err(());},
        };

        if tmp_value.is_null(){
            return Err(());
        }

        let value = tmp_value.into_static();
        Ok(Arc::new(JsonValue{
            json: json,
            value: value,
        }))
    }
}

impl DataFrame for JsonValue{
    fn clone(&self)->Box<dyn DataFrame>{
        let new = self.value.clone_static();
        return Box::new(JsonValue{
            json: self.json.clone(),
            value: new,
        });
    }
    fn serialize(&self)->String{
        self.value.encode()
    }
    fn delete_key(&mut self, key: &ElementValue)-> HandResult {
        delete_key(key.element.as_slice(), &mut self.value);
        return HandResult::Ok(RealValue::None);
    }
    fn get_key_value(&self, key: &ElementValue) -> HandResult {
        let v = get_key_value(key.element.as_slice(), &self.value);
        if let Some(v) = v{
            return HandResult::Ok(v);
        }else{
            return HandResult::Err(());
        }
    }
    fn set_key_value(&mut self, k: &ElementValue, v: RealValue) -> HandResult {
        match v{
            RealValue::Utf8(v) => {
                let res = set_key_value(&k.element[..],
                              Value::String(Cow::owned(v.clone())),
                              &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::U8(v) => {
                let res = set_key_value(&k.element[..],
                              Value::Static(StaticNode::U64(v as u64)),
                              &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::U16(v) => {
                let res = set_key_value(&k.element[..],
                              Value::Static(StaticNode::U64(v as u64)),
                              &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::U32(v) => {
                let res = set_key_value(&k.element[..],
                              Value::Static(StaticNode::U64(v as u64)),
                              &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::U64(v) => {
                let res = set_key_value(&k.element[..],
                              Value::Static(StaticNode::U64(v)),
                              &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::I8(v) => {
                let res = set_key_value(k.element.as_slice(),
                              Value::Static(StaticNode::I64(v as i64)),
                                  &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::I16(v) => {
                let res = set_key_value(k.element.as_slice(),
                              Value::Static(StaticNode::I64(v as i64)),
                                  &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::I32(v) => {
                let res = set_key_value(k.element.as_slice(),
                              Value::Static(StaticNode::I64(v as i64)),
                                  &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::I64(v) => {
                let res = set_key_value(k.element.as_slice(),
                              Value::Static(StaticNode::I64(v)),
                                  &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::F32(v) => {
                let res = set_key_value(k.element.as_slice(),
                              Value::Static(StaticNode::F64(v as f64)),
                                  &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::F64(v) => {
                let res = set_key_value(k.element.as_slice(),
                              Value::Static(StaticNode::F64(v)),
                                  &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::Boolean(v) => {
                let res = set_key_value(k.element.as_slice(),
                              Value::Static(StaticNode::Bool(v)),
                                  &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            },
            RealValue::DateTime(v) => {
                let res = set_key_value(k.element.as_slice(),
                                        Value::Static(StaticNode::I64(v.timestamp())),
                                        &mut self.value);
                if res{
                    return HandResult::Ok(RealValue::None);
                }else{
                    return HandResult::Err(());
                }
            }
            _ => {
                return HandResult::Err(());
            },
        }
    }
    fn key_exist(&self, k: &ElementValue)-> HandResult {
        return HandResult::Ok(RealValue::Boolean(key_exist(&k.element.as_slice(), &self.value)));
    }
    fn convert_value(&mut self, k: &ElementValue, new_type: Option<RealValueType>)-> HandResult {
        let v = convert_value(k.element.as_slice(), new_type, &mut self.value);
        if let Ok(_v) = v {
            return HandResult::Ok(RealValue::None);
        } else {
            return HandResult::Err(());
        }
    }
    fn encode_value(&mut self, key: &ElementValue)-> HandResult {
        encode_value(key.element.as_slice(), &mut self.value);
        return HandResult::Ok(RealValue::None);
    }
    fn decode_value(&mut self, key: &ElementValue)-> HandResult {
        decode_value(key.element.as_slice(), &mut self.value);
        return HandResult::Ok(RealValue::None);
    }
}

#[cfg(test)]
mod ValueTest{
    use tremor_value::{Object, Value, StaticNode};
    use simd_json::{Mutable, ValueAccess};
    use simd_json::cow::Cow;
    use crate::simd_json_derive::Deserialize;
    use crate::data_frame::json::value::{set_key_value, delete_key};

    #[test]
    fn test_json_value(){
        use crate::simd_json::Builder;
        use crate::tremor_value::Object;

        let key = vec!["aaa".to_string(),"bbb".to_string()];

        let mut desc =  format!(r#"{{"aaa":{{"bbb":[1,1.0,true,null],"ccc":"badger"}},"ddd":2}}"#);
        let mut value = Value::from_str(&mut desc).unwrap();
        //value.insert("eee", 4);
        //let res = set_key_value(key.as_slice(), Value::from(4), &mut value);

        delete_key(&key.as_slice(), &mut value);

        println!("value: {:?}", value);
    }
}
